﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using yzrilyzr.FAQ.client;
using yzrilyzr.FAQ.constants;
using yzrilyzr.FAQ.protocol;
using yzrilyzr.FAQ.utils;
using yzrilyzr.util;

namespace FAQ_UI
{
	/// <summary>
	/// ChatWindow.xaml 的交互逻辑
	/// </summary>
	public partial class MainWindow : Window, MsgPackReceiver, INotifyPropertyChanged
	{
		private Logger logger = new Logger("ToolBar");

		public event PropertyChangedEventHandler PropertyChanged;

		private NotifyIcon notifyIcon;
		private DispatcherTimer notifyIconTimer = new DispatcherTimer();

		protected void OnPropertyChanged(string propertyName)
		{
			if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
		}

		public string TaskIconTip
		{ get { return Title; } }

		public ImageSource TaskIconSource { get; set; }
		public GridLength ChatWidth { get; set; }
		private bool notifyIconStatus = false;
		private Icon NotifyIconAvatar;
		private Icon NotifyIconDef;
		private MenuItem nameMenuItem;

		public MainWindow(FAQID openID)
		{
			InitializeComponent();
			DataContext = this;
			MainWindowGrid.Background = Theme.BackBrush;
			FAQUtil.initFAQClient(openID.toInt());
			FAQUtil.eventBus.addReceiver(this);
			FAQUtil.client.addReceiver(this);
			if (FAQUtil.settings.contK(D.SETTINGS, "ServerAddress"))
			{
				logger.i("AutoConnect", FAQUtil.settings.getString(D.SETTINGS, "ServerAddress"));
				FAQUtil.client.connectTo(FAQUtil.settings.getString(D.SETTINGS, "ServerAddress"));
			}
			this.notifyIcon = new NotifyIcon();
			Drawable a = FAQUtil.getAvatar(openID);
			NotifyIconDef = System.Drawing.Icon.ExtractAssociatedIcon(System.Windows.Forms.Application.ExecutablePath);
			try
			{
				NotifyIconAvatar = FAQUtil.ToIcon(FAQUtil.getAvatar(openID));
			}
			catch (Exception e)
			{
				NotifyIconAvatar = NotifyIconDef;
			}
			notifyIcon.Icon = NotifyIconDef;
			this.notifyIcon.Visible = true;
			nameMenuItem = new MenuItem();
			MenuItem show = new MenuItem("打开FAQ");
			show.Click += new EventHandler(Show);
			MenuItem login = new MenuItem("上线");
			show.Click += new EventHandler(Login);
			MenuItem logout = new MenuItem("下线");
			show.Click += new EventHandler(Logout);
			MenuItem exit = new MenuItem("退出");
			exit.Click += new EventHandler(Close);
			MenuItem[] mis = new MenuItem[] { nameMenuItem, show, new MenuItem("-"), login, logout, new MenuItem("-"), exit };
			notifyIcon.ContextMenu = new ContextMenu(mis);
			this.notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler((o, e) =>
			{
				if (e.Button == MouseButtons.Left)
				{
					this.Show(o, e);
				}
			});
			setTitle();
			this.Closing += SettingWindow_Closing;
			MainWindowGrid.Background = Theme.BackBrush;
			DragView.Background = Theme.BackBrush;
			notifyIconTimer.Interval = new TimeSpan(0, 0, 0, 0, 250);
			notifyIconTimer.Tick += notifyIconTick;
			notifyIconTimer.IsEnabled = false;
		}

		private void notifyIconTick(object sender, EventArgs e)
		{
			if (notifyIconStatus) notifyIcon.Icon = NotifyIconDef;
			else notifyIcon.Icon = NotifyIconAvatar;
			notifyIconStatus = !notifyIconStatus;
		}

		private void Logout(object sender, EventArgs e)
		{
			FAQUtil.client.closeConnections();
		}

		private void Login(object sender, EventArgs e)
		{
			FAQUtil.client.closeConnections();
			if (FAQUtil.settings.contK(D.SETTINGS, "ServerAddress"))
			{
				FAQUtil.client.connectTo(FAQUtil.settings.getString(D.SETTINGS, "ServerAddress"));
			}
		}

		private void SettingWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			e.Cancel = true;
			Hide();
		}

		private void stopIconBlink()
		{
			notifyIconTimer.Stop();
			notifyIcon.Icon = NotifyIconDef;
		}

		private void Show(object sender, EventArgs e)
		{
			stopIconBlink();
			this.Show();
			this.WindowState = WindowState.Normal;
			this.Activate();
		}

		private void Close(object sender, EventArgs e)
		{
			notifyIcon.Visible = false;
			FAQUtil.eventBus.asyncSend(new BinMsgPack(App.APPLICATION_CLOSE));
		}

		public void receive(MsgPackTransfer mpt, MsgPack mp)
		{
			Dispatcher.Invoke(new Action(() =>
			{
				int i = mp.getCmd();
				if (i == ToolBar.TOOLBAR_SELECTOR)
				{
					string[] uris = new string[] { "MsgList", "FriendList", "GroupedList", "GroupList", "PubkeyList" };
					ListPage.Source = new Uri("/page/" + uris[mp.getInt(K.DATA)] + ".xaml", UriKind.Relative);
				}
				else if (i == App.APPLICATION_CLOSE)
				{
					notifyIcon.Visible = false;
					FAQUtil.client.closeMyData();
					FAQUtil.client.shutdown();
					Close();
					App.Current.Shutdown();
					Environment.Exit(0);
				}
				else if (i == App.OPEN_CHAT)
				{
					ChatWidth = new GridLength(2, GridUnitType.Star);
					FPubkeyPage.Visibility = Visibility.Collapsed;
					FChatPage.Visibility = Visibility.Visible;
					OnPropertyChanged(nameof(ChatWidth));
				}
				else if (i == App.CLOSE_CHAT)
				{
					ChatWidth = new GridLength(0);
					FChatPage.Visibility = Visibility.Collapsed;
					FPubkeyPage.Visibility = Visibility.Collapsed;
					OnPropertyChanged(nameof(ChatWidth));
				}
				else if (i == App.OPEN_PUBKEY_SET)
				{
					ChatWidth = new GridLength(2, GridUnitType.Star);
					FChatPage.Visibility = Visibility.Collapsed;
					FPubkeyPage.Visibility = Visibility.Visible;
					OnPropertyChanged(nameof(ChatWidth));
				}
				else if (i == C.LOGIN)
				{
					setTitle();
					FAQUtil.client.getCachedMsg();
					FAQUtil.client.getFriendsData();
				}
				else if (i == C.SESSION_STOPPED)
				{
					setTitle();
				}
				else if (i == C.USER_CACHE )
				{
					setTitle();
				}
				if (mp.isMsg() && (WindowState == WindowState.Minimized || Visibility == Visibility.Hidden))
				{
					FAQUtil.playFAQsound();
					notifyIconTimer.IsEnabled = true;
					notifyIconTimer.Start();
				}
			}));
		}

		private void setTitle()
		{
			nameMenuItem.Text = FAQClient.getName(FAQUtil.client.getFAQID()) + (FAQUtil.client.isLogin() ? "（在线）" : "（离线）");
			Title = FAQClient.getName(FAQUtil.client.getFAQID()) + " - FAQ" + (FAQUtil.client.isLogin() ? "（在线）" : "（离线）");
			this.notifyIcon.Text = Title;
		}

		private void MinWindow(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			WindowState = WindowState.Minimized;
		}

		private void MaxWindow(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			if (WindowState == WindowState.Maximized)
			{
				WindowState = WindowState.Normal;
				MaxButton.Text = "\ue3c6";
			}
			else
			{
				this.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
				this.MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;
				WindowState = WindowState.Maximized;
				MaxButton.Text = "\ue3e0";
			}
		}

		private void CloseWindow(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			Hide();
		}

		private void dragWindow(object sender, MouseButtonEventArgs e)
		{
			Window.GetWindow(this).DragMove();
		}

		private void Window_StateChanged(object sender, EventArgs e)
		{
			if (WindowState != WindowState.Minimized || Visibility != Visibility.Hidden)
			{
				stopIconBlink();
			}
		}
	}
}